/***************************************************************************
 *   KShootout - online shootout card game.                                *
 *   Copyright (C) 2008, 2009  MacJariel                                   *
 *                                                                         *
 *   KShootout is free software: you can redistribute it and/or modify     *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   KShootout is distributed in the hope that it will be useful,          *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with KShootout.  If not, see <http://www.gnu.org/licenses/>.    *
 ***************************************************************************/

#include "characterwidget.h"
#include "cardwidgetsizemgr.h"
#include "cardwidget.h"
#include "gamestructs.h"

#include <QTimerEvent>

using namespace client;

double pixelsPerSecond =  25;
const int timerInterval = 100;

CharacterWidget::CharacterWidget(QWidget *parent):
        QWidget(parent),
        m_lifePoints(0),
        m_sourceY(0),
        m_targetY(0),
        mp_backCard(0),
        mp_characterCard(0),
        m_animationTimer(0)
{
    connect(CardWidgetSizeMgr::instance(), SIGNAL(cardSizeChanged()),
            this, SLOT(updateWidgetSize()));
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    mp_backCard = new CardWidget(this);
    mp_backCard->setCharacterCard();
    mp_backCard->updatePixmap();
    mp_backCard->move(0, 0);
    mp_backCard->hide();

    mp_characterCard = new CardWidget(this);
    mp_characterCard->setCharacterCard();
    mp_characterCard->move(0, 0);
    mp_characterCard->hide();
}

/* virtual */
CharacterWidget::~CharacterWidget()
{
}

QString CharacterWidget::character() const
{
    return mp_characterCard->rCardData().name;
}

QSize CharacterWidget::sizeHint() const
{
    QSize size(CardWidgetSizeMgr::instance()->cardSize(CSR_Normal));
    size.rwidth() += CardWidgetSizeMgr::instance()->lifeLevel(5);
    return size;
}

void CharacterWidget::setGameActionMgr(GameActionMgr* gameActionMgr)
{
    mp_backCard->setGameActionMgr(gameActionMgr);
    mp_characterCard->setGameActionMgr(gameActionMgr);
}

void CharacterWidget::setPlayerId(PlayerId playerId)
{
    mp_backCard->setOwnerId(playerId);
    mp_characterCard->setOwnerId(playerId);
}

void CharacterWidget::setCharacter(const QString& character)
{
    m_character = character;
    mp_characterCard->setVisible(!m_character.isEmpty());
    mp_characterCard->setCharacterCard(character);
    mp_characterCard->updatePixmap();
    mp_backCard->setVisible(!m_character.isEmpty());
}

void CharacterWidget::setLifePoints(int lifePoints)
{
    if (lifePoints < 0 || lifePoints > 5) return;

    int oldLifePoints = m_lifePoints;
    m_lifePoints = lifePoints;
    if (oldLifePoints != m_lifePoints) {
        startAnimation();
    } else {
        emit animationFinished();
    }
}

void CharacterWidget::timerEvent(QTimerEvent* event)
{
    if (event->timerId() != m_animationTimer) {
        QWidget::timerEvent(event);
        return;
    }

    qreal progress = (m_time.elapsed() * pixelsPerSecond / 1000) / abs(m_sourceY - m_targetY);
    if (progress >= 1 || mp_characterCard->isHidden()) {
        mp_characterCard->move(mp_characterCard->x(), m_targetY);
        killTimer(m_animationTimer);
        emit animationFinished();
    } else {
        int currentY = m_sourceY + (int)((m_targetY - m_sourceY) * progress);
        mp_characterCard->move(mp_characterCard->x(), currentY);
    }
}

void CharacterWidget::startAnimation()
{
    m_sourceY = mp_characterCard->y();
    m_targetY = mp_backCard->y() + CardWidgetSizeMgr::instance()->lifeLevel(m_lifePoints);
    if (mp_characterCard->isHidden()) {
        mp_characterCard->move(mp_characterCard->x(), m_targetY);
        emit animationFinished();
    } else if (m_animationTimer == 0) {
        m_time.start();
        m_animationTimer = startTimer(timerInterval);
    }
}

void CharacterWidget::updateWidgetSize()
{
    int newY = CardWidgetSizeMgr::instance()->lifeLevel(m_lifePoints);
    mp_characterCard->move(mp_characterCard->x(), newY);
    updateGeometry();
}
